package com.ming.liteflow.controller;

import com.ming.common.beetl.util.Result;
import com.ming.common.beetl.util.StrUtil;
import com.ming.common.liteflow.context.IvyContext;
import com.ming.common.liteflow.core.chain.IvyChainUtil;
import com.ming.common.liteflow.core.flowexecutor.FlowExecutorUtil;
import com.ming.common.liteflow.core.node.CmpScriptUtil;
import com.ming.common.util.ClassFieldUtil;
import com.ming.common.xxljob.annotation.PermissionLimit;
import com.ming.common.liteflow.core.config.IvyConfig;
import com.ming.common.liteflow.core.execption.LiteFlowELException;
import com.ming.common.liteflow.vo.IvyConfigVo;
import com.ming.common.Options;
import com.ming.common.SortBy;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.page.PageResult;
import org.beetl.sql.core.query.LambdaQuery;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/liteflow/config")
public class LiteFlowConfigController {

    @Resource
    private SQLManager sqlManager;

    @PostMapping("/option")
    @PermissionLimit(limit = false)
    public Result<?> option(@RequestBody Map<String,Object> map) throws LiteFlowELException {
        return Result.OK(ClassFieldUtil.getFieldAnnoDescribe(IvyConfig.class, map));
    }

    @PostMapping("/options")
    @PermissionLimit(limit = false)
    public Result<?> elOptions(@RequestBody(required = false) Map<String,Object> map) throws LiteFlowELException {
        LambdaQuery<IvyConfig> query = sqlManager.lambdaQuery(IvyConfig.class);
        List<IvyConfig> list = query.select(IvyConfig::getId,IvyConfig::getConfigId,IvyConfig::getConfigName);
        return Result.OK(list);
    }

    @PostMapping("/page")
    @PermissionLimit(limit = false)
    public Result<PageResult<IvyConfig>> page(@RequestBody IvyConfigVo vo){
        LambdaQuery<IvyConfig> lambdaQuery = sqlManager.lambdaQuery(IvyConfig.class);
        lambdaQuery.andLike(IvyConfig::getConfigId, LambdaQuery.filterLikeEmpty(vo.getConfigId()));
        lambdaQuery.andLike(IvyConfig::getConfigName, LambdaQuery.filterLikeEmpty(vo.getConfigName()));
        lambdaQuery.andEq(IvyConfig::getRuleType, LambdaQuery.filterEmpty(vo.getRuleType()));
        Options options = vo.getOptions();
        List<SortBy> sortBy = options.getSortBy();
        for (SortBy sort : sortBy) {
            if ("desc".equalsIgnoreCase(sort.getOrder())) {
                lambdaQuery.desc(StrUtil.camelToSnake(sort.getKey()));
            } else {
                lambdaQuery.asc(StrUtil.camelToSnake(sort.getKey()));
            }
        }
        PageResult<IvyConfig> page = lambdaQuery.page(options.getPage(), options.getItemsPerPage());
        return Result.OK(page);
    }

    @PostMapping("/selectById")
    @PermissionLimit(limit = false)
    public Result<?> selectById(@RequestBody IvyConfig item){
        if(item.getId() != null){
            return Result.OK(sqlManager.lambdaQuery(IvyConfig.class).andEq(IvyConfig::getId, item.getId()).single());
        }
        return Result.OK(new IvyConfig());
    }

    @PostMapping("/add")
    @PermissionLimit(limit = false)
    public Result<?> add(@RequestBody IvyConfig item){
        LambdaQuery<IvyConfig> query = sqlManager.lambdaQuery(IvyConfig.class);
        int i = query.insert(item);
        return Result.OK(i);
    }

    @PostMapping("/update")
    @PermissionLimit(limit = false)
    public Result<Object> update(@RequestBody IvyConfig item){
        LambdaQuery<IvyConfig> lambdaQuery = sqlManager.lambdaQuery(IvyConfig.class);
        lambdaQuery.andNotEq(IvyConfig::getId, item.getId());
        lambdaQuery.andEq(IvyConfig::getConfigId, item.getConfigId());
        long count = lambdaQuery.count();
        if(count > 0){
            return Result.error("配置项ID重复");
        }
        int i = sqlManager.updateById(item);
        return Result.OK("更新成功", i);
    }

    @PostMapping("/delete")
    @PermissionLimit(limit = false)
    public Result<Integer> delete(@RequestBody IvyConfig item){
        LambdaQuery<IvyConfig> lambdaQuery = sqlManager.lambdaQuery(IvyConfig.class);
        lambdaQuery.andEq(IvyConfig::getId, item.getId());
        int i = lambdaQuery.delete();
        return Result.OK("删除成功",i);
    }

    @PostMapping("/exec")
    @PermissionLimit(limit = false)
    public Result<?> exec(@RequestBody IvyConfig item){
        IvyConfig ivyConfig = sqlManager.lambdaQuery(IvyConfig.class).andEq(IvyConfig::getId, item.getId()).single();
        FlowExecutor flowExecutor = FlowExecutorUtil.getFlowExecutor(ivyConfig);
        CmpScriptUtil.createNode("ivy_config_exec_test");
        IvyChainUtil.buildChain("ivy_config_exec_test","THEN(ivy_config_exec_test);");
        LiteflowResponse response = flowExecutor.execute2Resp("ivy_config_exec_test", null, new IvyContext());
        if(response.isSuccess()){
            String executeStepStrWithTime = response.getExecuteStepStrWithTime();
            System.out.println(executeStepStrWithTime);
            return Result.OK("调试成功！",null);
        }else{
            Exception cause = response.getCause();
            cause.printStackTrace();
            return Result.error("调试失败："+cause.getMessage());
        }

    }
}
